using BepuPhysics.Collidables;
using BepuUtilities;
using BepuUtilities.Memory;
using System.Diagnostics;
using System.Runtime.CompilerServices;
#if MYCODE
using BepuUtilities.Vectors;
#else
using System.Numerics;
#endif
namespace BepuPhysics.CollisionDetection
{
    public struct CompoundMeshReduction : ICollisionTestContinuation
    {
        public int RegionCount;
        public Buffer<(int Start, int Count)> ChildManifoldRegions;
        public Buffer<BoundingBox> QueryBounds;
        public Buffer<Triangle> Triangles;
        // 网格还原依赖于网格的所有三角形都在窗口B中,因为它们显示在网格碰撞任务中。
        // 然而,原始用户可能以未知的顺序提供了这一对,并触发了翻转。我们会在检查接触位置时补偿这一点。
        public bool RequiresFlip;
        // 三角形数组位于网格的局部空间中。为了针对它们测试任何联系人,我们需要能够转换联系人。
        public Quaternion MeshOrientation;
        // 这使用了所有非凸约简的逻辑,所以我们只需嵌套它。
        public NonconvexReduction Inner;

        public void Create(int childManifoldCount, BufferPool pool)
        {
            Inner.Create(childManifoldCount, pool);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public unsafe void OnChildCompleted<TCallbacks>(ref PairContinuation report, ref ConvexContactManifold manifold, ref CollisionBatcher<TCallbacks> batcher)
            where TCallbacks : struct, ICollisionCallbacks
        {
            Inner.OnChildCompleted(ref report, ref manifold, ref batcher);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void OnChildCompletedEmpty<TCallbacks>(ref PairContinuation report, ref CollisionBatcher<TCallbacks> batcher) where TCallbacks : struct, ICollisionCallbacks
        {
            Inner.OnChildCompletedEmpty(ref report, ref batcher);
        }

        public unsafe bool TryFlush<TCallbacks>(int pairId, ref CollisionBatcher<TCallbacks> batcher) where TCallbacks : struct, ICollisionCallbacks
        {
            Debug.Assert(Inner.ChildCount > 0);
            if (Inner.CompletedChildCount == Inner.ChildCount)
            {
                Matrix3x3.CreateFromQuaternion(MeshOrientation, out var meshOrientation);
                Matrix3x3.Transpose(meshOrientation, out var meshInverseOrientation);

                for (int i = 0; i < RegionCount; ++i)
                {
                    ref var region = ref ChildManifoldRegions[i];
                    if (region.Count > 0)
                    {
                        MeshReduction.ReduceManifolds(ref Triangles, ref Inner.Children, region.Start, region.Count, RequiresFlip, QueryBounds[i], meshOrientation, meshInverseOrientation, batcher.Pool);
                    }
                }

                // 既然边界平滑分析已经完成,我们就可以安全地清理连续资源了。
                batcher.Pool.Return(ref Triangles);
                batcher.Pool.Return(ref ChildManifoldRegions);
                batcher.Pool.Return(ref QueryBounds);
                Inner.Flush(pairId, ref batcher);
                return true;
            }
            return false;
        }

    }
}
